package com.clp.protocol.iec104.server;

import com.clp.protocol.iec104.definition.Tm;
import com.clp.protocol.iec104.definition.Ts;
import com.clp.protocol.iec104.server.pipeline.state.data.TaDataReactor;
import com.clp.protocol.iec104.server.pipeline.state.data.TcDataReactor;
import com.clp.protocol.iec104.server.pipeline.state.data.TotalCall100DataReactor;
import com.clp.protocol.iec104.server.pipeline.state.data.TotalCall101DataReactor;
import com.clp.protocol.core.common.Checkable;
import com.clp.protocol.core.utils.AssertUtil;
import lombok.Getter;

/**
 * 子站数据配置
 */
@Getter
public class SlaveDataConfig implements Checkable {
    public static final Tm.VaryType DEFAULT_TM_VARY_TYPE = Tm.VaryType.FLOAT;
    public static final Ts.VaryType DEFAULT_TS_VARY_TYPE = Ts.VaryType.ONE_POINT;

    private final TotalCall100DataReactor totalCall100DataReactor;
    private final TotalCall101DataReactor totalCall101DataReactor;
    private final TcDataReactor tcDataReactor;
    private final TaDataReactor taDataReactor;

    private final Tm.VaryType tmVaryType; // 变化遥测报文类型
    private final Ts.VaryType tsVaryType; // 变位遥信报文类型

    private SlaveDataConfig(Configurer cfgr) {
        this.totalCall100DataReactor = cfgr.totalCall100DataReactor;
        this.totalCall101DataReactor = cfgr.totalCall101DataReactor;
        this.tcDataReactor = cfgr.tcDataReactor;
        this.taDataReactor = cfgr.taDataReactor;

        this.tmVaryType = cfgr.tmVaryType;
        this.tsVaryType = cfgr.tsVaryType;
    }

    public static Configurer configurer() {
        return new Configurer();
    }

    @Override
    public void check() throws Throwable {
        AssertUtil.notNull(totalCall100DataReactor, "totalCall100DataReactor");
        AssertUtil.notNull(totalCall101DataReactor, "totalCall101DataReactor");
        AssertUtil.notNull(tcDataReactor, "tcDataReactor");
        AssertUtil.notNull(taDataReactor, "taDataReactor");
    }

    public static class Configurer {
        private TotalCall100DataReactor totalCall100DataReactor;
        private TotalCall101DataReactor totalCall101DataReactor;
        private TcDataReactor tcDataReactor;
        private TaDataReactor taDataReactor;
        private Tm.VaryType tmVaryType = DEFAULT_TM_VARY_TYPE; // 变化遥测报文类型
        private Ts.VaryType tsVaryType = DEFAULT_TS_VARY_TYPE; // 变位遥信报文类型

        public Configurer totalCall100DataReactor(TotalCall100DataReactor totalCall100DataReactor) {
            this.totalCall100DataReactor = totalCall100DataReactor;
            return this;
        }

        public Configurer totalCall101DataReactor(TotalCall101DataReactor totalCall101DataReactor) {
            this.totalCall101DataReactor = totalCall101DataReactor;
            return this;
        }

        public Configurer tcDataReactor(TcDataReactor tcDataReactor) {
            this.tcDataReactor = tcDataReactor;
            return this;
        }

        public Configurer taDataReactor(TaDataReactor taDataReactor) {
            this.taDataReactor = taDataReactor;
            return this;
        }

        public Configurer tmVaryType(Tm.VaryType tmVaryType) {
            this.tmVaryType = tmVaryType;
            return this;
        }

        public Configurer tsVaryType(Ts.VaryType tsVaryType) {
            this.tsVaryType = tsVaryType;
            return this;
        }

        public SlaveDataConfig configOk() {
            return new SlaveDataConfig(this);
        }

    }
}
